package cn.com.bluemoon.daps.model.core.file.excel.converter;

import com.alibaba.excel.converters.integer.IntegerStringConverter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import org.apache.commons.collections4.map.CaseInsensitiveMap;

import java.text.ParseException;
import java.util.Map;

/**
 * 获取针对kv映射关系的map 转换器
 *
 * @author Jarod.Kong
 * @date 2021/3/16 15:57
 */
public abstract class MyCodeAndNameIntegerStringConverter extends IntegerStringConverter {
    protected final CaseInsensitiveMap<Integer, String> CODE_AND_NAME_MAP = new CaseInsensitiveMap<Integer, String>();

    /**
     * map的kv => vk
     *
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> CaseInsensitiveMap<V, K> inverse(Map<K, V> map) {
        CaseInsensitiveMap<V, K> result = new CaseInsensitiveMap<V, K>(map.size());
        map.forEach((key, value) -> {
            result.put((V) value, (K) key);
        });
        return result;
    }

    protected void put(Integer code, String name) {
        CODE_AND_NAME_MAP.put(code, name);
    }

    /**
     * @return 获取针对kv映射关系的map
     */
    public CaseInsensitiveMap<Integer, String> getCodeAndName() {
        return CODE_AND_NAME_MAP;
    }

    public CaseInsensitiveMap<String, Integer> getNameAndCode() {
        return inverse(getCodeAndName());
    }

    protected Integer intDefaultValue() {
        return null;
    }

    protected String strDefaultValue() {
        return "";
    }

    @Override
    public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException {
        String indexTypeStr = cellData.getStringValue();
        if (indexTypeStr != null) {
            // 忽略敏感的问题，即使指定了类型，都会强行转为String，需要代码层面进行cast，否则会报错！！
            CaseInsensitiveMap<String, Integer> nameAndCode = getNameAndCode();
            Object code = nameAndCode.getOrDefault(indexTypeStr, intDefaultValue());
            if (code != null) {
                Integer indexType = Integer.parseInt(String.valueOf(code));
                return indexType;
            } else {
                return intDefaultValue();
            }
        }
        return super.convertToJavaData(cellData, contentProperty, globalConfiguration);
    }

    @Override
    public CellData<String> convertToExcelData(Integer indexType, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        if (indexType != null) {
            Object indexTypeStr = getCodeAndName().getOrDefault(indexType, strDefaultValue());
            // 忽略敏感的问题，即使指定了类型，都会强行转为String，需要代码层面进行cast，否则会报错！！
            if (indexTypeStr == null || "".equals(indexTypeStr)) {
                return new CellData<>(CellDataTypeEnum.STRING, strDefaultValue());
            }
            return new CellData<>(CellDataTypeEnum.STRING, String.valueOf(indexTypeStr));
        }
        return new CellData<>(CellDataTypeEnum.STRING, "");
    }
}
